// currencyConverter.ts

// 缓存条目接口
interface CacheEntry {
  rate: number;
  timestamp: number;
}

// 缓存信息接口
interface CacheInfoEntry {
  key: string;
  rate: number;
  age: string;
  expiresIn: string;
}

// 缓存信息接口
interface CacheInfo {
  size: number;
  entries: CacheInfoEntry[];
}

// API提供商类型
type ApiProvider = "frankfurter" | "exchangerate";

// API响应接口
interface FrankfurterResponse {
  rates: Record<string, number>;
  base: string;
  date: string;
}

interface ExchangeRateResponse {
  rates: Record<string, number>;
  base: string;
  date: string;
}

class CurrencyConverter {
  private apiProvider: ApiProvider;
  private readonly CACHE_DURATION: number = 12 * 60 * 60 * 1000; // 12小时缓存时间
  private readonly STORAGE_KEY: string = "currencyConverterCache";

  constructor(apiProvider: ApiProvider = "exchangerate") {
    this.apiProvider = apiProvider;
  }

  // 生成缓存键
  private getCacheKey(fromCurrency: string, toCurrency: string): string {
    return `${fromCurrency.toUpperCase()}_${toCurrency.toUpperCase()}`;
  }

  // 检查缓存是否有效
  private isValidCache(cacheEntry: CacheEntry | undefined): boolean {
    return (
      !!cacheEntry && Date.now() - cacheEntry.timestamp < this.CACHE_DURATION
    );
  }

  // 从chrome.storage获取缓存数据
  private async getFromCache(
    fromCurrency: string,
    toCurrency: string
  ): Promise<number | null> {
    const cacheKey = this.getCacheKey(fromCurrency, toCurrency);

    return new Promise((resolve) => {
      chrome.storage.sync.get([this.STORAGE_KEY], (result) => {
        const cache =
          (result[this.STORAGE_KEY] as Record<string, CacheEntry>) || {};
        const cacheEntry = cache[cacheKey];

        if (this.isValidCache(cacheEntry)) {
          resolve(cacheEntry.rate);
        } else {
          // 清除过期缓存
          if (cacheEntry) {
            this.removeFromCache(cacheKey);
          }
          resolve(null);
        }
      });
    });
  }

  // 从缓存中移除指定键
  private async removeFromCache(key: string): Promise<void> {
    return new Promise((resolve) => {
      chrome.storage.sync.get([this.STORAGE_KEY], (result) => {
        const cache =
          (result[this.STORAGE_KEY] as Record<string, CacheEntry>) || {};
        delete cache[key];

        chrome.storage.sync.set({ [this.STORAGE_KEY]: cache }, () => {
          resolve();
        });
      });
    });
  }

  // 保存到chrome.storage缓存
  private async saveToCache(
    fromCurrency: string,
    toCurrency: string,
    rate: number
  ): Promise<void> {
    const cacheKey = this.getCacheKey(fromCurrency, toCurrency);

    return new Promise((resolve) => {
      chrome.storage.sync.get([this.STORAGE_KEY], (result) => {
        const cache =
          (result[this.STORAGE_KEY] as Record<string, CacheEntry>) || {};

        cache[cacheKey] = {
          rate: rate,
          timestamp: Date.now(),
        };

        chrome.storage.sync.set({ [this.STORAGE_KEY]: cache }, () => {
          resolve();
        });
      });
    });
  }

  // 获取汇率数据
  private async fetchExchangeRate(
    fromCurrency: string,
    toCurrency: string
  ): Promise<number> {
    const currencies = [fromCurrency, toCurrency].map((c) => c.toUpperCase());

    try {
      let rate: number;

      if (this.apiProvider === "exchangerate") {
        const response = await fetch(
          `https://api.exchangerate-api.com/v4/latest/${currencies[0]}`
        );

        if (!response.ok) {
          throw new Error(`HTTP错误: ${response.status}`);
        }

        const data: ExchangeRateResponse = await response.json();
        rate = data.rates[currencies[1]];
      } else {
        const response = await fetch(
          `https://api.frankfurter.app/latest?from=${currencies[0]}&to=${currencies[1]}`
        );

        if (!response.ok) {
          throw new Error(`HTTP错误: ${response.status}`);
        }

        const data: FrankfurterResponse = await response.json();
        rate = data.rates[currencies[1]];
      }

      if (!rate) {
        throw new Error("无法获取汇率数据");
      }

      return rate;
    } catch (error) {
      throw new Error(
        `获取汇率失败: ${error instanceof Error ? error.message : "未知错误"}`
      );
    }
  }

  async convert(
    amount: number,
    fromCurrency: string,
    toCurrency: string
  ): Promise<number> {
    const currencies = [fromCurrency, toCurrency].map((c) => c.toUpperCase());

    // 如果是相同货币，直接返回原金额
    if (currencies[0] === currencies[1]) {
      return parseFloat(amount.toFixed(2));
    }

    try {
      // 先检查缓存
      const cachedRate = await this.getFromCache(currencies[0], currencies[1]);
      let rate: number;

      if (cachedRate !== null) {
        rate = cachedRate;
      } else {
        rate = await this.fetchExchangeRate(currencies[0], currencies[1]);

        // 保存到缓存
        await this.saveToCache(currencies[0], currencies[1], rate);
      }

      return parseFloat((amount * rate).toFixed(2));
    } catch (error) {
      throw new Error(
        `汇率转换失败: ${error instanceof Error ? error.message : "未知错误"}`
      );
    }
  }

  // 清空缓存
  async clearCache(): Promise<void> {
    return new Promise((resolve) => {
      chrome.storage.sync.remove(this.STORAGE_KEY, () => {
        resolve();
      });
    });
  }

  // 获取缓存信息
  async getCacheInfo(): Promise<CacheInfo> {
    return new Promise((resolve) => {
      chrome.storage.sync.get([this.STORAGE_KEY], (result) => {
        const now = Date.now();
        const cache =
          (result[this.STORAGE_KEY] as Record<string, CacheEntry>) || {};

        const cacheEntries: CacheInfoEntry[] = Object.entries(cache).map(
          ([key, value]) => {
            const age = Math.floor((now - value.timestamp) / 1000);
            const expiresIn = Math.max(0, this.CACHE_DURATION / 1000 - age);
            return {
              key,
              rate: value.rate,
              age: `${age}秒`,
              expiresIn: `${expiresIn}秒`,
            };
          }
        );

        resolve({
          size: Object.keys(cache).length,
          entries: cacheEntries,
        });
      });
    });
  }

  // 获取当前API提供商
  getApiProvider(): ApiProvider {
    return this.apiProvider;
  }

  // 设置API提供商
  setApiProvider(provider: ApiProvider): void {
    this.apiProvider = provider;
  }

  // 获取缓存大小
  async getCacheSize(): Promise<number> {
    const cacheInfo = await this.getCacheInfo();
    return cacheInfo.size;
  }
}

export default CurrencyConverter;
export type { ApiProvider, CacheInfo, CacheInfoEntry };
